/**
 * 
 */
package com.gopay.bis.psbc.ebank.operation;

import java.math.BigDecimal;
import java.net.URLDecoder;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;

import com.gopay.bis.common.util.BankLogUtils;
import com.gopay.bis.common.util.XMLBeanUtils;
import com.gopay.common.constants.bank.BankConstants;
import com.gopay.common.constants.bank.PsbcRespFieldConstants;
import com.gopay.common.constants.proccode.ProcCodeConstants;
import com.gopay.common.domain.bank.psbc.ebank.PsbcB2bMessage;
import com.gopay.common.domain.bank.psbc.ebank.PsbcQueryMessage;
import com.gopay.common.domain.bank.psbc.ebank.PsbcQueryResult;
import com.gopay.common.exception.GopayException;
import com.gopay.common.util.HttpsTransport;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.DomDriver;


/**
 * @PsbcB2bQueryHelper.java
 * @author Ryan
 * @2013-12-2 上午10:35:01  www.gopay.com.cn Inc.All rights reserved.
 */
public class PsbcB2bQueryHelper {

    private HttpsTransport httpsTransport;

    public String query(Map<String, String> param) throws GopayException {
        PsbcB2bMessage message = new PsbcB2bMessage();
        message.setOutStlmCd(BankConstants.BANK_LOGO_PSBC);
        try {
            httpsTransport.setUrl(param.get("url"));
            String result;
            BankLogUtils.printB2BQuerySendLog(message, param);
            result = (String) httpsTransport.submit(param);
            BankLogUtils.printB2BQueryBlackLog(message, result);
            return result;
        } catch (Exception e) {
            BankLogUtils.printB2BQueryExceptionLog(message, e);
            throw new GopayException(ProcCodeConstants.PROC_CODE_100E6036);
        }
    }

    public Map<String, String> buildQueryParam(PsbcB2bMessage message) {
        Map<String, String> param = new HashMap<String, String>();
        param.put("transName", message.getTranAbbr());
        param.put("Plain", message.getPlainMessage());
        param.put("Signature", message.getSignMessage());
        param.put("url", message.getQueryUrl());
        return param;
    }

    @SuppressWarnings("rawtypes")
    public PsbcB2bMessage parseMesage(String queryResultStr) throws GopayException {
       PsbcB2bMessage psbcQueryMessage = new PsbcB2bMessage();
        try {
            Map<String,Class> map = new HashMap<String,Class>();
            map.put("packet", PsbcQueryMessage.class);
            PsbcQueryResult result = (PsbcQueryResult) XMLBeanUtils.xml2Bean(map,queryResultStr);
            if (result != null) {
                if (result.getErrorCode() != null) {
                    psbcQueryMessage.setErrorCode(result.getErrorCode());
                    psbcQueryMessage.setRespCode(result.getErrorCode());
                    psbcQueryMessage.setErrorMsg(result.getErrorMsg());
                } else {
                    psbcQueryMessage.setPlainMessage(result.getPlain());
                    psbcQueryMessage.setSignMessage(result.getSignature());
                    psbcQueryMessage.setTransName(result.getTransName());
                    parsePlain(psbcQueryMessage);
                }
            }
            return psbcQueryMessage;
        } catch (Exception e) {
            throw new GopayException(ProcCodeConstants.PROC_CODE_100E6038);
        }
    }
    
    
    public void parsePlain(PsbcB2bMessage message) {
        String plain = message.getPlainMessage();
        String[] items = plain.split("\\|");
        for (String item : items) {
            int index = item.indexOf("=");
            if (PsbcRespFieldConstants.RSP_MERCCODE.equals(item.substring(0, index))) {
                message.setMercCode(item.substring(index + 1));
            } else if (PsbcRespFieldConstants.RSP_SETTDATE.equals(item.substring(0, index))) {
                message.setSettDate(item.substring(index + 1));
            } else if (PsbcRespFieldConstants.RSP_ACQSSN.equals(item.substring(0, index))) {
                message.setAcqSsn(item.substring(index + 1));
            } else if (PsbcRespFieldConstants.RSP_TERMSSN.equals(item.substring(0, index))) {
                message.setTermSsn(item.substring(index + 1));
            } else if (PsbcRespFieldConstants.RSP_TRANAMT.equals(item.substring(0, index))) {
                message.setTranAmt(item.substring(index + 1));
            } else if (PsbcRespFieldConstants.RSP_COMPFLAG.equals(item.substring(0, index))) {
                message.setCompFlag(item.substring(index + 1));
            } else if (PsbcRespFieldConstants.RSP_RESPCODE.equals(item.substring(0, index))) {
                message.setRespCode(item.substring(index + 1));
            }
        }
        message.setAmount(new BigDecimal(message.getTranAmt()));
        message.setOrderId(message.getTermSsn());
        message.setTermSsn(message.getTermSsn());

    }
    /**
     * @param xml
     * @return PsbcQueryResult
     * @throws Exception
     */
    @SuppressWarnings("unused")
    private PsbcQueryResult convertXml2Bean(String xml) throws Exception{
        PsbcQueryResult queryResult = new PsbcQueryResult();
        XStream xs = new XStream(new DomDriver());
        xs.autodetectAnnotations(true);
        xs.toXML(xml);
        queryResult = (PsbcQueryResult) xs.fromXML(URLDecoder.decode(xml,"UTF-8"));
        return queryResult;
    }

    /**
     * @param message
     */
    public void  parsePlainMessage(PsbcB2bMessage message){
        Map<String, String> tempMap = str2map(message.getPlainMessage());
        message.setMercCode((String) tempMap.get("MercCode"));
        message.setSettDate((String) tempMap.get("SettDate"));
        message.setAcqSsn((String) tempMap.get("AcqSsn"));
        message.setTermSsn((String) tempMap.get("TermSsn"));
        message.setTranAmt((String) tempMap.get("TranAmt"));
        message.setCompFlag((String) tempMap.get("CompFlag"));
        message.setRespCode((String) tempMap.get("RespCode"));
    }
    

    /**
     * @param plain
     * @return
     */
    private Map<String, String> str2map(String plain) {
        if (plain == null || plain.length() == 0) {
            return null;
        }
        LinkedHashMap<String, String> retMap = new LinkedHashMap<String, String>();
        String terms[] = plain.split("\\|");
        int len = terms.length;
        for (int i = 0; i < len; i++) {
            String term = terms[i];
            int index = term.indexOf("=");
            retMap.put(term.substring(0, index), term.substring(index + 1));
        }
        return retMap;
    }
    /**
     * @param httpsTransport
     *            the httpsTransport to set
     */
    public void setHttpsTransport(HttpsTransport httpsTransport) {
        this.httpsTransport = httpsTransport;
    }
}
